/**
 * RenderLoop - 渲染循环管理器
 * 统一管理所有渲染任务，支持帧率控制、页面可见性检测、性能监控
 */

import PerformanceMonitor from './PerformanceMonitor.js'

class RenderLoop {
  constructor(options = {}) {
    this.isRunning = false
    this.isPaused = false
    this.frameId = null
    this.targetFPS = options.targetFPS || 60
    this.frameInterval = 1000 / this.targetFPS
    this.lastFrameTime = 0
    this.renderers = []
    this.performanceMonitor = new PerformanceMonitor()
    this.autoAdjustFPS = options.autoAdjustFPS !== false
    this.minFPS = options.minFPS || 15
    
    // 绑定方法
    this.tick = this.tick.bind(this)
    this.handleVisibilityChange = this.handleVisibilityChange.bind(this)
    
    // 监听页面可见性
    this.setupVisibilityListener()
    
    // 监听性能问题
    this.setupPerformanceListener()
  }

  /**
   * 启动渲染循环
   */
  start() {
    if (this.isRunning) return
    
    this.isRunning = true
    this.isPaused = false
    this.lastFrameTime = performance.now()
    
    console.log('RenderLoop started, target FPS:', this.targetFPS)
    this.tick(this.lastFrameTime)
  }

  /**
   * 停止渲染循环
   */
  stop() {
    if (!this.isRunning) return
    
    this.isRunning = false
    this.isPaused = false
    
    if (this.frameId !== null) {
      cancelAnimationFrame(this.frameId)
      this.frameId = null
    }
    
    console.log('RenderLoop stopped')
  }

  /**
   * 暂停渲染
   */
  pause() {
    if (!this.isRunning || this.isPaused) return
    
    this.isPaused = true
    console.log('RenderLoop paused')
  }

  /**
   * 恢复渲染
   */
  resume() {
    if (!this.isRunning || !this.isPaused) return
    
    this.isPaused = false
    this.lastFrameTime = performance.now()
    console.log('RenderLoop resumed')
    this.tick(this.lastFrameTime)
  }

  /**
   * 渲染循环主函数
   */
  tick(timestamp) {
    if (!this.isRunning) return
    
    // 如果暂停，不继续调度
    if (this.isPaused) return
    
    // 计算时间差
    const deltaTime = timestamp - this.lastFrameTime
    
    // 帧率控制
    if (deltaTime >= this.frameInterval) {
      const renderStartTime = performance.now()
      
      // 执行所有渲染器
      this.renderers.forEach(renderer => {
        try {
          if (renderer && typeof renderer.render === 'function') {
            renderer.render(timestamp, deltaTime)
          }
        } catch (error) {
          console.error('Renderer error:', error)
        }
      })
      
      // 记录渲染时间
      const renderTime = performance.now() - renderStartTime
      this.performanceMonitor.recordRenderTime(renderTime)
      
      // 更新性能监控
      this.performanceMonitor.update(timestamp)
      
      // 更新上次渲染时间
      this.lastFrameTime = timestamp - (deltaTime % this.frameInterval)
    }
    
    // 继续下一帧
    this.frameId = requestAnimationFrame(this.tick)
  }

  /**
   * 添加渲染器
   */
  addRenderer(renderer) {
    if (!renderer) return
    
    if (!this.renderers.includes(renderer)) {
      this.renderers.push(renderer)
      console.log('Renderer added, total:', this.renderers.length)
    }
  }

  /**
   * 移除渲染器
   */
  removeRenderer(renderer) {
    const index = this.renderers.indexOf(renderer)
    if (index > -1) {
      this.renderers.splice(index, 1)
      console.log('Renderer removed, total:', this.renderers.length)
    }
  }

  /**
   * 调整目标FPS
   */
  adjustFPS(targetFPS) {
    if (targetFPS < this.minFPS) {
      targetFPS = this.minFPS
    }
    
    if (targetFPS !== this.targetFPS) {
      this.targetFPS = targetFPS
      this.frameInterval = 1000 / this.targetFPS
      console.log('FPS adjusted to:', this.targetFPS)
    }
  }

  /**
   * 设置页面可见性监听
   */
  setupVisibilityListener() {
    // uni-app环境下的页面可见性监听
    if (typeof uni !== 'undefined') {
      try {
        // 监听页面显示
        uni.onAppShow(() => {
          console.log('App show, resuming render loop')
          this.resume()
        })
        
        // 监听页面隐藏
        uni.onAppHide(() => {
          console.log('App hide, pausing render loop')
          this.pause()
        })
      } catch (error) {
        console.warn('Failed to setup uni-app visibility listener:', error)
      }
    }
    
    // H5环境下的页面可见性监听
    if (typeof document !== 'undefined') {
      document.addEventListener('visibilitychange', this.handleVisibilityChange)
    }
  }

  /**
   * 处理页面可见性变化
   */
  handleVisibilityChange() {
    if (document.hidden) {
      console.log('Page hidden, pausing render loop')
      this.pause()
    } else {
      console.log('Page visible, resuming render loop')
      this.resume()
    }
  }

  /**
   * 设置性能监听
   */
  setupPerformanceListener() {
    if (!this.autoAdjustFPS) return
    
    // 监听低性能事件
    this.performanceMonitor.on('low-performance', (data) => {
      console.warn('Low performance detected, adjusting FPS and applying optimizations')
      const newFPS = Math.max(this.minFPS, Math.floor(this.targetFPS * 0.75))
      this.adjustFPS(newFPS)
      
      // 通知所有渲染器应用优化
      this.renderers.forEach(renderer => {
        if (renderer && typeof renderer.applyOptimization === 'function') {
          renderer.applyOptimization(data.fps)
        }
      })
    })
    
    // 监听严重性能问题
    this.performanceMonitor.on('critical-performance', (data) => {
      console.error('Critical performance detected, reducing FPS to minimum and applying aggressive optimizations')
      this.adjustFPS(this.minFPS)
      
      // 通知所有渲染器应用优化
      this.renderers.forEach(renderer => {
        if (renderer && typeof renderer.applyOptimization === 'function') {
          renderer.applyOptimization(data.fps)
        }
      })
    })
  }

  /**
   * 获取性能指标
   */
  getMetrics() {
    return {
      ...this.performanceMonitor.getMetrics(),
      targetFPS: this.targetFPS,
      isRunning: this.isRunning,
      isPaused: this.isPaused,
      rendererCount: this.renderers.length
    }
  }

  /**
   * 获取性能监控器
   */
  getPerformanceMonitor() {
    return this.performanceMonitor
  }

  /**
   * 销毁渲染循环
   */
  destroy() {
    this.stop()
    this.renderers = []
    
    // 移除可见性监听
    if (typeof document !== 'undefined') {
      document.removeEventListener('visibilitychange', this.handleVisibilityChange)
    }
    
    console.log('RenderLoop destroyed')
  }
}

// 创建全局单例
let globalRenderLoop = null

export function getGlobalRenderLoop(options) {
  if (!globalRenderLoop) {
    globalRenderLoop = new RenderLoop(options)
  }
  return globalRenderLoop
}

export default RenderLoop
